package co.edu.uniandes.services;

import java.io.File;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import co.edu.uniandes.dto.Evento;
import co.edu.uniandes.services.constantes.ConsultaConstantes;

/**
 * Se encarga del manejo de los eventos con respecto a la persistencia
 * @author Diego Alejandro Olivera Rios <diegoalejo14@gmail.com>
 *
 */
public class ServicioEvento extends UnicastRemoteObject implements IServicioEvento{

	/**
	 * Contructor
	 * @throws RemoteException
	 */
	public ServicioEvento() throws RemoteException {
		super();
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 *Se encarga de guardar un nuevo evento en la BD
	 *@param objeto Evento que va ser almacenado en base de datos
	 *@throws Cuando se presenta algun problema con la persistencia 
	 */
	@Override
	public void insertar(Evento objeto) throws Exception {
		PreparedStatement ps=null;

		try{
			if(objeto==null || objeto.getFechaFin()==null || objeto.getFechaInicio()==null){
				throw new Exception("No se puede guardar el evento ya que tiene datos sin diligenciar");
			}
			Connection conexion=ConexionBD.getInstance().getConection();
			ps=	conexion.prepareStatement(ConsultaConstantes.INSERT_EVENTO);
			ps.setString(1, objeto.getNombre());
			ps.setInt(2, objeto.getEstado());
			ps.setTimestamp(3, new Timestamp(objeto.getFechaInicio().getTime()));
			ps.setTimestamp(4, new Timestamp(objeto.getFechaFin().getTime()) );
			ps.setInt(5, objeto.getTipoEvento());
			ps.setInt(6, objeto.getCiudad());
			ps.execute();
		}catch (Exception e) {
			throw e;
		}finally{
			if(ps !=null && !ps.isClosed()){
				ps.close();
			}

		}
	}

	/**
	 * Se encarga de obtener todos los eventos que se encuentran en 
	 * base de datos
	 * @throws Se lanza cuando se presentan problemas con la conexion de BD 
	 */
	@Override
	public List<Evento> consultar() throws Exception {

		List<Evento> retorno=new ArrayList<Evento>();
		PreparedStatement ps=null;
		ResultSet rs=null;
		try{
			Connection con=ConexionBD.getInstance().getConection();
			ps=con.prepareStatement(ConsultaConstantes.CONSULTA_EVENTO);
			rs=ps.executeQuery();
			Evento evento=null;

			while(rs.next()){
				evento=new Evento();
				evento.setId(rs.getInt("id"));
				evento.setNombre(rs.getString("nombre"));
				evento.setEstado(rs.getInt("estado"));
				evento.setFechaInicio(rs.getTimestamp("fechaInicio"));
				evento.setFechaFin(rs.getTimestamp("fechaFin"));
				evento.setTipoEvento(rs.getInt("idTipoEvento"));
				evento.setCiudad(rs.getInt("idCiudad"));
				retorno.add(evento);
			}
			rs.close();
		}catch (Exception e) {
			throw e;
		}finally{
			if(rs!=null && !rs.isClosed()){
				rs.close();
			}
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}

		return retorno;
	}


	/**
	 *Se encarga de eliminar un evento de acuerdo a su id
	 *@param id Identificacion del evento
	 *@throws Cuando la identificacion del evento es nula o cuando se presenta problemas
	 *con la BD 
	 */
	@Override
	public void eliminar(Integer id) throws Exception {

		PreparedStatement ps=null;
		if(id==null){
			throw new Exception(" La identificacion del evento que se va a eliminar es nula");
		}
		try{
			Connection connection=ConexionBD.getInstance().getConection();
			ps=connection.prepareStatement(ConsultaConstantes.DELETE_EVENTO);
			ps.setInt(1, id);
			ps.execute();
		}catch (Exception e) {
			throw e;
		}finally{
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
	}

	/**
	 *Se encarga de actualizar los datos de un evento creado anteriomente
	 *@param objeto Objeto que va a ser modificado
	 *@throws Cuando el evento, las fechas o el id estan vac�os o cuando se presenta alg�n problema
	 *con la base de datos
	 */
	@Override
	public void actualizar(Evento objeto) throws Exception {
		PreparedStatement ps=null;
		try{

			if(objeto==null || objeto.getFechaFin()==null || objeto.getFechaInicio()==null|| objeto.getId()==0){
				throw new Exception("No se puede guardar el evento ya que tiene datos sin diligenciar");
			}
			Connection conexion=ConexionBD.getInstance().getConection();
			ps=conexion.prepareStatement(ConsultaConstantes.UPDATE_EVENTO);
			ps.setString(1, objeto.getNombre());
			ps.setInt(2, objeto.getEstado());
			ps.setDate(3, new Date(objeto.getFechaInicio().getTime()) );
			ps.setDate(4, new Date(objeto.getFechaFin().getTime()) );
			ps.setInt(5, objeto.getTipoEvento());
			ps.setInt(6, objeto.getCiudad());
			ps.setInt(7, objeto.getId());
			ps.execute();
		}catch (Exception e) {
			throw e;
		}finally{
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
	}


	public void cargar(String ruta) throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ( );
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document  documento = builder.parse( new File(ruta) );
		Node nodoRaiz = documento.getFirstChild();
		NodeList listaNodosHijos = nodoRaiz.getChildNodes();
		Node unNodoHijo;
		NamedNodeMap atributos;
		Node tipoEvento;
		Node ciudad;
		Node estado;
		Node nombre;
		Node fechaInicio;
		Node fechaFin;
		Evento evento;
		for (int i=0; i<listaNodosHijos.getLength(); i++){
			evento=new Evento();
			unNodoHijo = listaNodosHijos.item(i);
			if(unNodoHijo.getNodeType()!=Node.ELEMENT_NODE){
				continue;
				
			}
			Element elemento=	(Element)unNodoHijo;
			NodeList lista=	elemento.getElementsByTagName("evento");
			for(int j=0;j<lista.getLength();j++){
				NodeList lista1=	lista.item(i).getChildNodes();
				System.out.println(lista1.item(0).getNodeValue());
			}
			atributos = unNodoHijo.getAttributes();
			tipoEvento=atributos.getNamedItem("tipoEvento");
			ciudad=atributos.getNamedItem("ciudad");
			estado=atributos.getNamedItem("estado");
			nombre=atributos.getNamedItem("nombre");
			fechaInicio=atributos.getNamedItem("fechaInicio");
			fechaFin=atributos.getNamedItem("fechaFin");
			evento.setTipoEvento(Integer.parseInt(tipoEvento.getNodeValue()));
			evento.setCiudad(Integer.parseInt(ciudad.getNodeValue()));
			evento.setEstado(Integer.parseInt(estado.getNodeValue()));
			evento.setNombre(nombre.getNodeValue());
			evento.setFechaInicio(new java.util.Date(fechaInicio.getNodeValue()) );
			evento.setFechaFin(new java.util.Date(fechaFin.getNodeValue()) );
			insertar(evento);
		}
	}


//	public static void main(String[] args) {
//		try{
//		new ServicioEvento().cargar("D:\\LATITUDE\\Documents\\ECOS\\CAIS\\TspEntrega2\\prueba.xml.txt");
//		}catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
	

}
